package com.capital.serviceImp;

import com.capital.entity.CfnInfo;
import com.capital.dao.CfnMapper;
import com.capital.entity.StrategyInfo;
import com.capital.service.CfnService;
import com.eastmoney.QuantCase;
import com.eastmoney.entity.EQData;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.web.ResourceProperties;
import org.springframework.stereotype.Service;
import org.springframework.web.bind.annotation.RequestBody;

import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

@Slf4j
@Service
public class CfnServiceImpl implements CfnService {

	@Autowired
	CfnMapper cfnMapper;

	public String testCfn() {
		String ret = "test cfn";
		log.info(ret);
		return ret;
	}

	public String addCfn(@RequestBody Map<String, Object> body) {
		String datetime = body.get("datetime").toString();
		String eitime = body.get("eitime").toString();
		String code = body.get("code").toString();
		String content = body.get("content").toString();
		String title = body.get("title").toString();
		String infoCode = body.get("infoCode").toString();
		String medianname = body.get("medianname").toString();
		String url = body.get("url").toString();
		String date = datetime.substring(0, 10);
		CfnInfo cfnInfo = new CfnInfo(datetime, eitime, code, content, title, infoCode, medianname, url, date);
        log.info("add cfn: {}", cfnInfo);
		cfnMapper.addCfn(cfnInfo);
        return cfnInfo.toString();
	}

	public CfnInfo getCfnByInfoCode(String infoCode) {
		log.info("get cfn by info code: {}", infoCode);
		CfnInfo cfnInfo = cfnMapper.getCfnByInfoCode(infoCode);
		log.info("cfn info: {}", cfnInfo);
		return cfnInfo;
	}

	public boolean requestCfnFromEastmoney(@RequestBody Map<String, Object> body) {
		String codes = body.get("codes").toString();
		String content = body.get("content").toString();
		int emode = Integer.parseInt(body.get("emode").toString());
		String options = body.get("options").toString();
		return addCfnFromEastmoney(codes, content, emode, options);
	}

	public boolean addCfnFromEastmoney(String codes, String content, int emode, String options) {
		List<CfnInfo> ret = new ArrayList<>();
		EQData eQData = QuantCase.getCfn(codes, content, emode, options);
		if (eQData.getErrCode() != 0) {
			log.info("request cfn Error, {}", eQData.getErrString());
			if("EQERR_CODE_INVALIED".equals(eQData.getErrString()) || "EQERR_INFO_SEARCH_NODATA".equals(eQData.getErrString())) {
				return true;
			}
			return false;
		} else {
			log.info(eQData.toString());
		}
		Object[][][] objs = eQData.getValueArray();
		if(objs == null) {
			return true;
		}
		for(int i = 0; i < objs.length; ++i) {
			for(int j = 0; j < objs[0].length; ++j) {
				if(objs[0][0].length < 8) {
					log.warn("add cfn from eastmoney, data error: {}", objs[0][0]);
					continue;
				}
				CfnInfo cfnInfo = new CfnInfo(objs[0][0]);
				ret.add(cfnInfo);
				log.info("add cfn from eastmoney: {}", cfnInfo);
				cfnMapper.addCfn(cfnInfo);
			}
		}
		return true;
	}

	public void timerAddCfn() {
		String yesterday = getPreviousDate(1);
		if(yesterday.equals(getCfnDate())) {
			log.info("timer add cfn, already added, time: {}", yesterday);
			return;
		}
		final int maxDays = 5;
		for(int i = 1; i <= maxDays; i++) {
			String startDateStr = getPreviousDate(maxDays);
			String endDateStr = getPreviousDate(i);
//			String codes = getStrategyStockCode(endDateStr);
//			if(codes.isEmpty()) {
//				continue;
//			}
			String[] codes = getStrategyStockCodeArray(endDateStr);
			// 可能存在无效的股票代码,所以逐个调用
			for(int j = 0; j < codes.length; j++) {
				boolean success = addCfns(codes[j], startDateStr, endDateStr);
				if (!success) {
					return;
				}
			}
		}
		setCfnDate(yesterday);
	}

	private String[] getStrategyStockCodeArray(String dateStr) {
		List<StrategyInfo> ss = getStrategyInfo(dateStr);
		String[] codes = new String[ss.size()];
		for(int i = 0; i < ss.size(); i++) {
			codes[i] = ss.get(i).getStock_code();
		}
		return codes;
	}

	private String getStrategyStockCode(String dateStr) {
		String codes = "";
		List<StrategyInfo> ss = getStrategyInfo(dateStr);
		for(int i = 0; i < ss.size(); i++) {
			if(!codes.isEmpty()) {
				codes += ",";
			}
			codes += ss.get(i).getStock_code();
		}
		return codes;
	}

	private boolean addCfns(String codes, String starttime, String endtime) {
		String content = "report,tradeinfo";
		int emode = 1;
		String options = "starttime=" + starttime + ",endtime=" + endtime + ",count=0";
		log.info("timer add cfn, codes: {}, options: {}", codes, options);
        return addCfnFromEastmoney(codes, content, emode, options);
	}

	private String getPreviousDate(int day) {
		LocalDate localDate= LocalDate.now().minusDays(day);
		DateTimeFormatter formatter = DateTimeFormatter.ofPattern("YYYY-MM-dd");
		return formatter.format(localDate);
	}

	private List<StrategyInfo> getStrategyInfo(String dateStr) {
		List<StrategyInfo> ret = cfnMapper.getStrategyInfo(dateStr);
		if (ret == null) {
			return null;
		}
		for(int i = 0; i < ret.size(); i++) {
			log.info("i: {}, value: {}", i, ret.get(i));
		}
		return ret;
	}

	public String setCfnDate(String date) {
		cfnMapper.setCfnDate(date);
		return date;
	}

	public String getCfnDate() {
		String ret = cfnMapper.getCfnDate();
		return ret;
	}

}
